package com.zylix.simon.checking.notes;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import android.os.Environment;
import android.util.Log;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.*;
import javax.xml.xpath.*;


public class XMLAdapter {
	private static final String TAG = "XMLAdapter";
	
    Element theItem=null, theName=null, theCheck=null, root=null;
    Document xmldoc = null;
    List<CheckItemData> checkitem_list;
    
	public XMLAdapter(){
		DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
        try {
            factory.setIgnoringElementContentWhitespace(true);
            
            DocumentBuilder db=factory.newDocumentBuilder();
            xmldoc = db.parse(CheckNoteActivity.class.getClassLoader()
					.getResourceAsStream("checklist.xml"));
            root=xmldoc.getDocumentElement();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
	}
	
	public XMLAdapter(String full_path){
		checkitem_list = new ArrayList<CheckItemData>();
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		try{
            factory.setIgnoringElementContentWhitespace(true);
            DocumentBuilder db=factory.newDocumentBuilder();
            xmldoc = db.parse(new FileInputStream(full_path));
            root=xmldoc.getDocumentElement();
		}catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
	}
	
	public List<CheckItemData> getXMLData(){
		//data_dump();
		//Log.d(TAG, checkitem_list.toString());		
		NodeList result =selectNodes("/checklist/item[@id>=0]", root);		
		for(int i = 0; i < result.getLength(); i++)
		{
			CheckItemData cid = new CheckItemData();
			theItem = (Element)result.item(i);
			cid.setItemId(i);
			cid.setItemTitle(theItem.getElementsByTagName("name").item(0).getTextContent());
			if(theItem.getElementsByTagName("check").item(0).getTextContent().equals("false"))
				cid.setItemChecked(false);
			else
				cid.setItemChecked(true);
			checkitem_list.add(cid);
		}
		//this.data_dump();
		return checkitem_list;
	}
	
	public void appendNode(int id, String item, boolean isChecked){
		//Create a new node and add into the DOM tree
		theItem = xmldoc.createElement("item");
		theItem.setAttribute("id", new Integer(id).toString());
		
		theName = xmldoc.createElement("name");
		theName.setTextContent(item);
		theItem.appendChild(theName);
		
		theCheck = xmldoc.createElement("check");
		if(!isChecked)
			theCheck.setTextContent("false");
		else
			theCheck.setTextContent("true");
		theItem.appendChild(theCheck);
		root.appendChild(theItem);
	}	
	
	public void deleteNode(int id)
	{
		String base_path = "/checklist/item[@id=";		
		theItem=(Element) selectSingleNode(base_path + id +"]", root);
        Log.i(TAG, "----Delete the item with id----");
        theItem.getParentNode().removeChild(theItem);
	}
	
	public boolean modifyItemNamebyID(int id, String newItem){
		boolean ret = true;
		String base_path = "/checklist/item[@id=";
		theItem = (Element) selectSingleNode(base_path + id + "]", root);
		if(theItem == null)
			ret = false;
		theItem.getElementsByTagName("name").item(0).setTextContent(newItem);
		return ret;
	}
	
	public boolean modifyCheckStatusbyID(int id, boolean checked){
		boolean ret = true;
		String base_path = "/checklist/item[@id=";
		theItem = (Element) selectSingleNode(base_path + id + "]", root);
		if(theItem == null)
			ret = false;
		if(!checked)
			theItem.getElementsByTagName("check").item(0).setTextContent("false");
		else
			theItem.getElementsByTagName("check").item(0).setTextContent("true");
		return ret;
	}
	
	//Find the node, return the first finding node
    private Node selectSingleNode(String express, Object source) {
        Node result=null;
        XPathFactory xpathFactory=XPathFactory.newInstance();
        XPath xpath=xpathFactory.newXPath();
        try {
            result=(Node) xpath.evaluate(express, source, XPathConstants.NODE);
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }        
        return result;
    }
    
    public NodeList selectNodes(String express, Object source) {
        NodeList result=null;
        XPathFactory xpathFactory=XPathFactory.newInstance();
        XPath xpath=xpathFactory.newXPath();
        try {
            result=(NodeList) xpath.evaluate(express, source, XPathConstants.NODESET);
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
        return result;
    }
    
    private String prepareExternalStorage()
    {
    	String ret=null;
        if(!Environment.getExternalStorageState().equals(Environment.MEDIA_REMOVED) ){
        	File SDCardpath = Environment.getExternalStorageDirectory();
            File myDataPath = new File( SDCardpath.getAbsolutePath() + "/myCheckList/" );
            if( !myDataPath.exists() ) myDataPath.mkdirs();
                ret = myDataPath.getPath();
        }
		return ret;   	
    }
    
    public String saveXml(String fileName){
    	Document m_xmldoc = xmldoc;
    	String path = prepareExternalStorage();
    	//Log.i(TAG, path + "/" + fileName);
    	TransformerFactory transFactory=TransformerFactory.newInstance();
        try {
            Transformer transformer = transFactory.newTransformer();
            transformer.setOutputProperty("indent", "yes");

            DOMSource source=new DOMSource();
            source.setNode(m_xmldoc);
            StreamResult result=new StreamResult();
            result.setOutputStream(new FileOutputStream(path + "/" + fileName));
            
            transformer.transform(source, result);
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }   
    	return path;
    }
    
    //debug only
    private void data_dump(){
    	if(checkitem_list != null){
    		Log.i(TAG, "Item List Length is " + checkitem_list.size());
    		for(int i=0; i<checkitem_list.size(); i++)
    			 checkitem_list.get(i).dump_data();
    	}else{
    		Log.i(TAG, "Error NULL data dumping!");
    	}
    }
}
